package com.lagou.java;

import io.netty.channel.ChannelFuture;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;

import javax.xml.crypto.Data;
import java.beans.beancontext.BeanContextServiceAvailableEvent;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Classname ServerBootstrap
 * @Description TODO
 * @Date 2020/7/22 13:03
 * @Created by pc
 */

@SpringBootApplication
@ConfigurationProperties(prefix = "netty")
public class ServerBootstrap {

    public static ConfigurableApplicationContext applicationContext = null;

    private static String host;

    private static int port1;

//    private static String host2;

    private static int port2;

    public static Map<Integer, Thread> serverTreads = new HashMap<>();
    public static Map<Integer, ChannelFuture> serverServices = new HashMap<>();


    public static void main(String[] args) throws Exception {
        // 获取 spring 应用上下文， 用于获取 bean
        applicationContext = SpringApplication.run(ServerBootstrap.class, args);
        NettyServer.initZkClient();
        // 启动 netty 服务
        Thread serverA = new Thread(() -> {
            ChannelFuture serviceA = NettyServer.startServer(host, port1);
//            String data = NettyServer.getData(NettyServer.basePath);
//            System.out.println("===>" + data);
        });
        serverA.start();
        serverTreads.put(port1, serverA);
        Thread serverB = new Thread(() -> {
            ChannelFuture serviceB = NettyServer.startServer(host, port2);
//            String data = NettyServer.getData(NettyServer.basePath);
//            System.out.println("===>" + data);
        });
        serverB.start();
        serverTreads.put(port2, serverB);
        System.out.println(serverServices);
        // 阻塞主线程
//        TimeUnit.DAYS.sleep(Integer.MAX_VALUE);

    }

    // 通过反射调用名为 methodName 的方法
    public static <T> Object invoke(String className, String methodName, Object[] args) throws Exception {
        Object invoke = null;
        // 获取 bean
        Object source = getBeanByClassName(className);

        if (source == null) {
            return "名为：" + className + " 的服务不存在， 请核对后重试！ ";
        }

        // 调用方法
        Method[] declaredMethods = source.getClass().getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            if (declaredMethod.getName().equals(methodName)) {
                invoke = declaredMethod.invoke(source, args);
            }
        }

        return invoke == null ?
                "调用的方法不合法, 方法为：" + className + "#" + methodName
                : invoke;
    }

    // 通过 class 类型获取 bean
    public static Object getBeanByClassName (String className) throws ClassNotFoundException {
        return applicationContext.getBean(Class.forName(className));
    }

    // 通过 beanName 获取 bean
    public static Object getBeanByName (String beanName) {
        return applicationContext.getBean(beanName);
    }

    public void setHost(String host) {
        ServerBootstrap.host = host;
    }

    public void setPort1(int port1) {
        ServerBootstrap.port1 = port1;
    }

    public void setPort2(int port2) {
        ServerBootstrap.port2 = port2;
    }

    public static int getPort1() {
        return port1;
    }

    public static int getPort2() {
        return port2;
    }

    public static String getHost() {
        return host;
    }
}
